{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "container=Container(width=200, height=200) rectangles=[Rectangle(width=17, height=89, value=1), Rectangle(width=29, height=70, value=1), Rectangle(width=60, height=12, value=1), Rectangle(width=33, height=10, value=1), Rectangle(width=6, height=17, value=1), Rectangle(width=9, height=2, value=1), Rectangle(width=17, height=8, value=1), Rectangle(width=3, height=9, value=1), Rectangle(width=14, height=11, value=1), Rectangle(width=31, height=36, value=1), Rectangle(width=12, height=53, value=1), Rectangle(width=10, height=10, value=1), Rectangle(width=26, height=9, value=1), Rectangle(width=19, height=123, value=1), Rectangle(width=16, height=20, value=1), Rectangle(width=28, height=79, value=1), Rectangle(width=46, height=13, value=1), Rectangle(width=70, height=18, value=1), Rectangle(width=9, height=44, value=1), Rectangle(width=30, height=5, value=1), Rectangle(width=11, height=5, value=1), Rectangle(width=39, height=24, value=1), Rectangle(width=31, height=8, value=1), Rectangle(width=21, height=36, value=1), Rectangle(width=28, height=17, value=1), Rectangle(width=6, height=35, value=1), Rectangle(width=12, height=30, value=1), Rectangle(width=18, height=14, value=1), Rectangle(width=10, height=41, value=1), Rectangle(width=17, height=21, value=1), Rectangle(width=6, height=14, value=1), Rectangle(width=11, height=44, value=1), Rectangle(width=17, height=80, value=1), Rectangle(width=56, height=10, value=1), Rectangle(width=5, height=27, value=1), Rectangle(width=101, height=17, value=1), Rectangle(width=7, height=41, value=1), Rectangle(width=10, height=34, value=1), Rectangle(width=68, height=19, value=1), Rectangle(width=50, height=55, value=1), Rectangle(width=39, height=6, value=1), Rectangle(width=12, height=40, value=1), Rectangle(width=3, height=1, value=1), Rectangle(width=9, height=35, value=1), Rectangle(width=36, height=21, value=1), Rectangle(width=15, height=63, value=1), Rectangle(width=21, height=9, value=1), Rectangle(width=15, height=50, value=1), Rectangle(width=6, height=13, value=1), Rectangle(width=9, height=22, value=1), Rectangle(width=30, height=7, value=1), Rectangle(width=37, height=9, value=1), Rectangle(width=6, height=1, value=1), Rectangle(width=16, height=55, value=1), Rectangle(width=25, height=7, value=1), Rectangle(width=17, height=9, value=1), Rectangle(width=46, height=22, value=1), Rectangle(width=18, height=29, value=1), Rectangle(width=45, height=26, value=1), Rectangle(width=36, height=33, value=1), Rectangle(width=11, height=22, value=1), Rectangle(width=8, height=4, value=1), Rectangle(width=10, height=5, value=1), Rectangle(width=2, height=11, value=1), Rectangle(width=27, height=48, value=1), Rectangle(width=26, height=4, value=1), Rectangle(width=7, height=3, value=1), Rectangle(width=7, height=22, value=1), Rectangle(width=13, height=16, value=1), Rectangle(width=19, height=12, value=1), Rectangle(width=18, height=6, value=1), Rectangle(width=6, height=16, value=1), Rectangle(width=12, height=32, value=1), Rectangle(width=17, height=89, value=1), Rectangle(width=29, height=70, value=1), Rectangle(width=60, height=12, value=1), Rectangle(width=33, height=10, value=1), Rectangle(width=6, height=17, value=1), Rectangle(width=9, height=2, value=1), Rectangle(width=17, height=8, value=1), Rectangle(width=3, height=9, value=1), Rectangle(width=14, height=11, value=1), Rectangle(width=31, height=36, value=1), Rectangle(width=12, height=53, value=1), Rectangle(width=10, height=10, value=1), Rectangle(width=26, height=9, value=1), Rectangle(width=19, height=123, value=1), Rectangle(width=16, height=20, value=1), Rectangle(width=28, height=79, value=1), Rectangle(width=46, height=13, value=1), Rectangle(width=70, height=18, value=1), Rectangle(width=9, height=44, value=1), Rectangle(width=30, height=5, value=1), Rectangle(width=11, height=5, value=1), Rectangle(width=39, height=24, value=1), Rectangle(width=31, height=8, value=1), Rectangle(width=21, height=36, value=1), Rectangle(width=28, height=17, value=1), Rectangle(width=6, height=35, value=1), Rectangle(width=12, height=30, value=1), Rectangle(width=18, height=14, value=1), Rectangle(width=10, height=41, value=1), Rectangle(width=17, height=21, value=1), Rectangle(width=6, height=14, value=1), Rectangle(width=11, height=44, value=1), Rectangle(width=17, height=80, value=1), Rectangle(width=56, height=10, value=1), Rectangle(width=5, height=27, value=1), Rectangle(width=101, height=17, value=1), Rectangle(width=7, height=41, value=1), Rectangle(width=10, height=34, value=1), Rectangle(width=68, height=19, value=1), Rectangle(width=50, height=55, value=1), Rectangle(width=39, height=6, value=1), Rectangle(width=12, height=40, value=1), Rectangle(width=3, height=1, value=1), Rectangle(width=9, height=35, value=1), Rectangle(width=36, height=21, value=1), Rectangle(width=15, height=63, value=1), Rectangle(width=21, height=9, value=1), Rectangle(width=15, height=50, value=1), Rectangle(width=6, height=13, value=1), Rectangle(width=9, height=22, value=1), Rectangle(width=30, height=7, value=1), Rectangle(width=37, height=9, value=1), Rectangle(width=6, height=1, value=1), Rectangle(width=16, height=55, value=1), Rectangle(width=25, height=7, value=1), Rectangle(width=17, height=9, value=1), Rectangle(width=46, height=22, value=1), Rectangle(width=18, height=29, value=1), Rectangle(width=45, height=26, value=1), Rectangle(width=36, height=33, value=1), Rectangle(width=11, height=22, value=1), Rectangle(width=8, height=4, value=1), Rectangle(width=10, height=5, value=1), Rectangle(width=2, height=11, value=1), Rectangle(width=27, height=48, value=1), Rectangle(width=26, height=4, value=1), Rectangle(width=7, height=3, value=1), Rectangle(width=7, height=22, value=1), Rectangle(width=13, height=16, value=1), Rectangle(width=19, height=12, value=1), Rectangle(width=18, height=6, value=1), Rectangle(width=6, height=16, value=1), Rectangle(width=12, height=32, value=1)]\n"
     ]
    }
   ],
   "source": [
    "from pathlib import Path\n",
    "from solver import Instance\n",
    "\n",
    "with open(Path(\"./instances/hopper/TN5e.json\"), \"r\") as file:\n",
    "    instance = Instance.model_validate_json(file.read())\n",
    "    instance = Instance(\n",
    "        container=instance.container,\n",
    "        rectangles=instance.rectangles + instance.rectangles,\n",
    "    )\n",
    "print(instance)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "from solver import RectangleKnapsackWithoutRotationsModel"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "model = RectangleKnapsackWithoutRotationsModel(instance)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Starting CP-SAT solver v9.8.3296\n",
      "Parameters: max_time_in_seconds: 60 log_search_progress: true relative_gap_limit: 0.01\n",
      "Setting number of workers to 16\n",
      "\n",
      "Initial optimization model '': (model_fingerprint: 0x22dc157099af7241)\n",
      "#Variables: 438 (#bools: 146 in objective)\n",
      "  - 146 Booleans in [0,1]\n",
      "  - 2 in [0,77]\n",
      "  - 2 in [0,99]\n",
      "  - 2 in [0,111]\n",
      "  - 2 in [0,120]\n",
      "  - 2 in [0,121]\n",
      "  - 4 in [0,130]\n",
      "  - 2 in [0,132]\n",
      "  - 2 in [0,137]\n",
      "  - 2 in [0,140]\n",
      "  - 2 in [0,144]\n",
      "  - 4 in [0,145]\n",
      "  - 2 in [0,147]\n",
      "  - 4 in [0,150]\n",
      "  - 2 in [0,152]\n",
      "  - 4 in [0,154]\n",
      "  - 2 in [0,155]\n",
      "  - 4 in [0,156]\n",
      "  - 4 in [0,159]\n",
      "  - 2 in [0,160]\n",
      "  - 4 in [0,161]\n",
      "  - 2 in [0,163]\n",
      "  - 8 in [0,164]\n",
      "  - 4 in [0,165]\n",
      "  - 2 in [0,166]\n",
      "  - 4 in [0,167]\n",
      "  - 2 in [0,168]\n",
      "  - 4 in [0,169]\n",
      "  - 6 in [0,170]\n",
      "  - 4 in [0,171]\n",
      "  - 4 in [0,172]\n",
      "  - 4 in [0,173]\n",
      "  - 6 in [0,174]\n",
      "  - 2 in [0,175]\n",
      "  - 2 in [0,176]\n",
      "  - 8 in [0,178]\n",
      "  - 8 in [0,179]\n",
      "  - 2 in [0,180]\n",
      "  - 6 in [0,181]\n",
      "  - 8 in [0,182]\n",
      "  - 16 in [0,183]\n",
      "  - 8 in [0,184]\n",
      "  - 4 in [0,185]\n",
      "  - 6 in [0,186]\n",
      "  - 6 in [0,187]\n",
      "  - 12 in [0,188]\n",
      "  - 10 in [0,189]\n",
      "  - 14 in [0,190]\n",
      "  - 18 in [0,191]\n",
      "  - 6 in [0,192]\n",
      "  - 10 in [0,193]\n",
      "  - 16 in [0,194]\n",
      "  - 8 in [0,195]\n",
      "  - 4 in [0,196]\n",
      "  - 6 in [0,197]\n",
      "  - 4 in [0,198]\n",
      "  - 4 in [0,199]\n",
      "#kInterval: 292 (#enforced: 292)\n",
      "#kNoOverlap2D: 1 (#rectangles: 146, #optional: 146)\n",
      "\n",
      "Starting presolve at 0.00s\n",
      "  9.77e-05s  0.00e+00d  [DetectDominanceRelations] \n",
      "  5.24e-04s  0.00e+00d  [PresolveToFixPoint] #num_loops=2 #num_dual_strengthening=1 \n",
      "  2.49e-06s  0.00e+00d  [ExtractEncodingFromLinear] \n",
      "[Symmetry] Graph for symmetry has 1'315 nodes and 2'044 arcs.\n",
      "[Symmetry] Symmetry computation done. time: 0.000285604 dtime: 0.00024034\n",
      "  1.75e-03s  3.07e-05d  [Probe] #probed=292 \n",
      "  6.38e-06s  0.00e+00d  [MaxClique] \n",
      "  7.44e-05s  0.00e+00d  [DetectDominanceRelations] \n",
      "  4.59e-04s  0.00e+00d  [PresolveToFixPoint] #num_loops=2 #num_dual_strengthening=1 \n",
      "  4.03e-05s  0.00e+00d  [DetectDuplicateConstraints] \n",
      "  1.69e-06s  0.00e+00d  [DetectDifferentVariables] \n",
      "  2.44e-06s  0.00e+00d  [DetectDominatedLinearConstraints] \n",
      "  3.34e-06s  0.00e+00d  [ProcessSetPPC] \n",
      "  3.66e-06s  0.00e+00d  [FindAlmostIdenticalLinearConstraints] \n",
      "  2.45e-06s  0.00e+00d  [FindBigHorizontalLinearOverlap] \n",
      "  7.15e-06s  3.65e-06d  [FindBigVerticalLinearOverlap] \n",
      "  3.10e-06s  0.00e+00d  [MergeClauses] \n",
      "  5.71e-05s  0.00e+00d  [DetectDominanceRelations] \n",
      "  3.62e-04s  0.00e+00d  [PresolveToFixPoint] #num_loops=1 #num_dual_strengthening=1 \n",
      "  3.79e-05s  0.00e+00d  [ExpandObjective] \n",
      "\n",
      "Presolve summary:\n",
      "  - 0 affine relations were detected.\n",
      "  - rule 'TODO dual: add implied bound' was applied 1'752 times.\n",
      "  - rule 'TODO dual: only one blocking enforced constraint?' was applied 1'752 times.\n",
      "  - rule 'presolve: 0 unused variables removed.' was applied 1 time.\n",
      "  - rule 'presolve: iteration' was applied 1 time.\n",
      "\n",
      "Presolved optimization model '': (model_fingerprint: 0xbf1eaac0b5d9aeaf)\n",
      "#Variables: 438 (#bools: 146 in objective)\n",
      "  - 146 Booleans in [0,1]\n",
      "  - 2 in [0,77]\n",
      "  - 2 in [0,99]\n",
      "  - 2 in [0,111]\n",
      "  - 2 in [0,120]\n",
      "  - 2 in [0,121]\n",
      "  - 4 in [0,130]\n",
      "  - 2 in [0,132]\n",
      "  - 2 in [0,137]\n",
      "  - 2 in [0,140]\n",
      "  - 2 in [0,144]\n",
      "  - 4 in [0,145]\n",
      "  - 2 in [0,147]\n",
      "  - 4 in [0,150]\n",
      "  - 2 in [0,152]\n",
      "  - 4 in [0,154]\n",
      "  - 2 in [0,155]\n",
      "  - 4 in [0,156]\n",
      "  - 4 in [0,159]\n",
      "  - 2 in [0,160]\n",
      "  - 4 in [0,161]\n",
      "  - 2 in [0,163]\n",
      "  - 8 in [0,164]\n",
      "  - 4 in [0,165]\n",
      "  - 2 in [0,166]\n",
      "  - 4 in [0,167]\n",
      "  - 2 in [0,168]\n",
      "  - 4 in [0,169]\n",
      "  - 6 in [0,170]\n",
      "  - 4 in [0,171]\n",
      "  - 4 in [0,172]\n",
      "  - 4 in [0,173]\n",
      "  - 6 in [0,174]\n",
      "  - 2 in [0,175]\n",
      "  - 2 in [0,176]\n",
      "  - 8 in [0,178]\n",
      "  - 8 in [0,179]\n",
      "  - 2 in [0,180]\n",
      "  - 6 in [0,181]\n",
      "  - 8 in [0,182]\n",
      "  - 16 in [0,183]\n",
      "  - 8 in [0,184]\n",
      "  - 4 in [0,185]\n",
      "  - 6 in [0,186]\n",
      "  - 6 in [0,187]\n",
      "  - 12 in [0,188]\n",
      "  - 10 in [0,189]\n",
      "  - 14 in [0,190]\n",
      "  - 18 in [0,191]\n",
      "  - 6 in [0,192]\n",
      "  - 10 in [0,193]\n",
      "  - 16 in [0,194]\n",
      "  - 8 in [0,195]\n",
      "  - 4 in [0,196]\n",
      "  - 6 in [0,197]\n",
      "  - 4 in [0,198]\n",
      "  - 4 in [0,199]\n",
      "#kInterval: 292 (#enforced: 292)\n",
      "#kNoOverlap2D: 1 (#rectangles: 146, #optional: 146)\n",
      "\n",
      "Preloading model.\n",
      "#Bound   0.01s best:-inf  next:[-0,146]   initial_domain\n",
      "[Symmetry] Graph for symmetry has 1'315 nodes and 2'044 arcs.\n",
      "[Symmetry] Symmetry computation done. time: 0.000136996 dtime: 0.00024034\n",
      "#Model   0.01s var:438/438 constraints:293/293\n",
      "\n",
      "Starting search at 0.01s with 16 workers.\n",
      "11 full problem subsolvers: [core, default_lp, lb_tree_search, max_lp, no_lp, objective_lb_search, probing, pseudo_costs, quick_restart, quick_restart_no_lp, reduced_costs]\n",
      "4 first solution subsolvers: [fj_long_default, fj_short_default, fs_random, fs_random_quick_restart]\n",
      "13 incomplete subsolvers: [feasibility_pump, graph_arc_lns, graph_cst_lns, graph_dec_lns, graph_var_lns, packing_precedences_lns, packing_rectangles_lns, packing_slice_lns, rins/rens, rnd_cst_lns, rnd_var_lns, scheduling_precedences_lns, violation_ls]\n",
      "3 helper subsolvers: [neighborhood_helper, synchronization_agent, update_gap_integral]\n",
      "#1       0.01s best:-0    next:[1,146]    fj_short_default(batch:1 #lin_moves:0 #lin_evals:0 #weight_updates:0)\n",
      "#Bound   0.01s best:-0    next:[1,122]    default_lp (initial_propagation)\n",
      "#2       0.01s best:1     next:[2,122]    quick_restart_no_lp (fixed_bools=0/438)\n",
      "#3       0.02s best:2     next:[3,122]    quick_restart (fixed_bools=0/452)\n",
      "#4       0.03s best:3     next:[4,122]    quick_restart (fixed_bools=0/744)\n",
      "#5       0.04s best:4     next:[5,122]    quick_restart (fixed_bools=0/1036)\n",
      "#6       0.05s best:5     next:[6,122]    quick_restart_no_lp (fixed_bools=0/1036)\n",
      "#7       0.05s best:6     next:[7,122]    quick_restart_no_lp (fixed_bools=0/1328)\n",
      "#8       0.06s best:73    next:[74,122]   probing (fixed_bools=0/371)\n",
      "#9       0.19s best:74    next:[75,122]   probing (fixed_bools=0/396)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "#10      0.31s best:75    next:[76,122]   quick_restart_no_lp (fixed_bools=0/1658)\n",
      "#11      0.43s best:76    next:[77,122]   quick_restart_no_lp (fixed_bools=0/1684)\n",
      "#12      0.57s best:77    next:[78,122]   quick_restart_no_lp (fixed_bools=0/1760)\n",
      "#13      0.69s best:78    next:[79,122]   quick_restart_no_lp (fixed_bools=0/1768)\n",
      "#14      1.00s best:79    next:[80,122]   quick_restart (fixed_bools=0/2215)\n",
      "#15      1.12s best:80    next:[81,122]   quick_restart (fixed_bools=0/2287)\n",
      "#16      1.98s best:81    next:[82,122]   quick_restart_no_lp (fixed_bools=0/2134)\n",
      "#17      2.62s best:82    next:[83,122]   quick_restart_no_lp (fixed_bools=0/2378)\n",
      "#18      2.98s best:83    next:[84,122]   quick_restart_no_lp (fixed_bools=0/2502)\n",
      "#19      3.00s best:84    next:[85,122]   quick_restart_no_lp (fixed_bools=0/2503)\n",
      "#20      3.04s best:85    next:[86,122]   quick_restart_no_lp (fixed_bools=0/2507)\n",
      "#21      3.35s best:86    next:[87,122]   quick_restart (fixed_bools=0/3363)\n",
      "#22      4.48s best:87    next:[88,122]   quick_restart (fixed_bools=0/3673)\n",
      "#23      5.12s best:88    next:[89,122]   quick_restart_no_lp (fixed_bools=0/3140)\n",
      "#24      8.33s best:89    next:[90,122]   quick_restart_no_lp (fixed_bools=0/3626)\n",
      "#25      8.54s best:90    next:[91,122]   quick_restart (fixed_bools=0/5416)\n",
      "#26     10.33s best:91    next:[92,122]   quick_restart_no_lp (fixed_bools=0/4103)\n",
      "#27     15.39s best:92    next:[93,122]   graph_var_lns (d=0.29 s=32 t=0.10 p=0.00 stall=0 h=auto_l0)\n",
      "#28     15.78s best:93    next:[94,122]   packing_precedences_lns (d=0.50 s=24 t=0.10 p=0.00 stall=0 h=auto_l0)\n",
      "#29     16.35s best:94    next:[95,122]   quick_restart_no_lp (fixed_bools=0/5004)\n",
      "#30     16.66s best:95    next:[96,122]   rnd_var_lns (d=0.29 s=30 t=0.10 p=0.00 stall=0 h=auto_l0)\n",
      "#31     17.69s best:96    next:[97,122]   graph_dec_lns (d=0.29 s=35 t=0.10 p=0.00 stall=0 h=auto_l0)\n",
      "#32     28.75s best:98    next:[99,122]   packing_slice_lns (d=0.29 s=38 t=0.10 p=0.00 stall=0 h=auto_l0)\n",
      "#33     36.88s best:99    next:[100,122]  quick_restart_no_lp (fixed_bools=0/8060)\n",
      "#34     45.16s best:100   next:[101,122]  quick_restart_no_lp (fixed_bools=0/8432)\n",
      "#35     46.72s best:101   next:[102,122]  quick_restart (fixed_bools=0/11579)\n",
      "#36     53.39s best:102   next:[103,122]  quick_restart (fixed_bools=0/12197)\n",
      "#37     55.00s best:103   next:[104,122]  quick_restart_no_lp (fixed_bools=0/8854)\n",
      "#38     59.96s best:105   next:[106,122]  rnd_var_lns (d=0.31 s=55 t=0.10 p=0.33 stall=1 h=auto_l0)\n",
      "\n",
      "Task timing                             n [     min,      max]      avg      dev     time         n [     min,      max]      avg      dev    dtime\n",
      "                        'core':         1 [   1.00m,    1.00m]    1.00m   0.00ns    1.00m         1 [   2.64s,    2.64s]    2.64s   0.00ns    2.64s\n",
      "                  'default_lp':         1 [   1.00m,    1.00m]    1.00m   0.00ns    1.00m         1 [   1.26s,    1.26s]    1.26s   0.00ns    1.26s\n",
      "            'feasibility_pump':         4 [ 33.75us,   1.35ms] 399.66us 550.67us   1.60ms         2 [882.00ns, 882.00ns] 882.00ns   0.00ns   1.76us\n",
      "             'fj_long_default':         0 [  0.00ns,   0.00ns]   0.00ns   0.00ns   0.00ns         0 [  0.00ns,   0.00ns]   0.00ns   0.00ns   0.00ns\n",
      "            'fj_short_default':         1 [468.50us, 468.50us] 468.50us   0.00ns 468.50us         0 [  0.00ns,   0.00ns]   0.00ns   0.00ns   0.00ns\n",
      "                   'fs_random':         1 [  2.02ms,   2.02ms]   2.02ms   0.00ns   2.02ms         0 [  0.00ns,   0.00ns]   0.00ns   0.00ns   0.00ns\n",
      "     'fs_random_quick_restart':         1 [  1.95ms,   1.95ms]   1.95ms   0.00ns   1.95ms         0 [  0.00ns,   0.00ns]   0.00ns   0.00ns   0.00ns\n",
      "               'graph_arc_lns':         3 [   1.20s,    8.84s]    4.25s    3.30s   12.76s         3 [ 28.64ms, 100.04ms]  76.23ms  33.65ms 228.68ms\n",
      "               'graph_cst_lns':         3 [   1.68s,   11.40s]    5.10s    4.46s   15.31s         3 [ 21.44ms, 100.03ms]  73.82ms  37.04ms 221.47ms\n",
      "               'graph_dec_lns':         3 [   1.03s,   10.52s]    4.63s    4.20s   13.90s         3 [  6.34ms, 100.06ms]  68.80ms  44.17ms 206.40ms\n",
      "               'graph_var_lns':         3 [   1.22s,   13.10s]    5.40s    5.45s   16.21s         3 [ 10.88ms, 100.01ms]  70.30ms  42.01ms 210.89ms\n",
      "              'lb_tree_search':         1 [   1.00m,    1.00m]    1.00m   0.00ns    1.00m         1 [   1.92s,    1.92s]    1.92s   0.00ns    1.92s\n",
      "                      'max_lp':         1 [   1.00m,    1.00m]    1.00m   0.00ns    1.00m         1 [   2.96s,    2.96s]    2.96s   0.00ns    2.96s\n",
      "                       'no_lp':         1 [   1.00m,    1.00m]    1.00m   0.00ns    1.00m         1 [854.27ms, 854.27ms] 854.27ms   0.00ns 854.27ms\n",
      "         'objective_lb_search':         1 [   1.00m,    1.00m]    1.00m   0.00ns    1.00m         1 [967.84ms, 967.84ms] 967.84ms   0.00ns 967.84ms\n",
      "     'packing_precedences_lns':         3 [  13.87s,   16.41s]   15.15s    1.03s   45.45s         3 [ 97.17ms, 100.01ms]  99.06ms   1.34ms 297.18ms\n",
      "      'packing_rectangles_lns':         3 [  11.13s,   12.10s]   11.63s 398.05ms   34.90s         3 [100.00ms, 100.00ms] 100.00ms  31.18ns 300.00ms\n",
      "           'packing_slice_lns':         3 [  10.62s,   12.65s]   11.34s 926.67ms   34.01s         3 [100.00ms, 100.00ms] 100.00ms 415.46ns 300.00ms\n",
      "                     'probing':         1 [   1.00m,    1.00m]    1.00m   0.00ns    1.00m         1 [346.67ms, 346.67ms] 346.67ms   0.00ns 346.67ms\n",
      "                'pseudo_costs':         1 [   1.00m,    1.00m]    1.00m   0.00ns    1.00m         1 [   4.00s,    4.00s]    4.00s   0.00ns    4.00s\n",
      "               'quick_restart':         1 [   1.00m,    1.00m]    1.00m   0.00ns    1.00m         1 [   1.07s,    1.07s]    1.07s   0.00ns    1.07s\n",
      "         'quick_restart_no_lp':         1 [   1.00m,    1.00m]    1.00m   0.00ns    1.00m         1 [815.77ms, 815.77ms] 815.77ms   0.00ns 815.77ms\n",
      "               'reduced_costs':         1 [   1.00m,    1.00m]    1.00m   0.00ns    1.00m         1 [   1.60s,    1.60s]    1.60s   0.00ns    1.60s\n",
      "                   'rins/rens':         4 [   1.74s,    9.57s]    6.10s    2.81s   24.42s         4 [ 14.25ms, 100.01ms]  73.17ms  35.14ms 292.68ms\n",
      "                 'rnd_cst_lns':         3 [396.11us, 437.08us] 412.77us  17.58us   1.24ms         0 [  0.00ns,   0.00ns]   0.00ns   0.00ns   0.00ns\n",
      "                 'rnd_var_lns':         4 [   2.28s,   13.31s]    5.20s    4.69s   20.78s         4 [  7.70ms, 100.01ms]  58.93ms  41.70ms 235.74ms\n",
      "  'scheduling_precedences_lns':         3 [   7.77s,   15.52s]   11.70s    3.16s   35.11s         3 [ 26.71ms, 100.01ms]  75.57ms  34.55ms 226.71ms\n",
      "                'violation_ls':         3 [  1.50ms,   34.46s]   15.59s   14.26s   46.77s         3 [  1.52us,   1.58ms] 580.93us 709.92us   1.74ms\n",
      "\n",
      "Search stats                   Bools  Conflicts   Branches  Restarts  BoolPropag  IntegerPropag\n",
      "                     'core':   9'159     25'966    755'490       293  24'202'139      1'344'215\n",
      "               'default_lp':   7'947      7'860    695'287       382   4'849'948      2'263'362\n",
      "                'fs_random':     146          0         22        22           0             23\n",
      "  'fs_random_quick_restart':     146          0         32        32           0             33\n",
      "           'lb_tree_search':     599     66'259    112'687       299   2'284'014      1'264'534\n",
      "                   'max_lp':   5'014     55'234    714'207       403   6'834'524      2'937'042\n",
      "                    'no_lp':   8'164      8'443    762'594       401   5'007'666      1'598'461\n",
      "      'objective_lb_search':   7'186      7'074    451'330       358   3'727'847      1'483'384\n",
      "                  'probing':   3'619      6'091    286'752     1'326   1'091'564        878'253\n",
      "             'pseudo_costs':   4'609     86'815    802'897       393  11'669'165      3'755'515\n",
      "            'quick_restart':  12'319      8'626  1'167'640     1'122   5'779'989      1'821'051\n",
      "      'quick_restart_no_lp':   9'268      8'911  1'002'658     1'133   4'499'719      1'701'290\n",
      "            'reduced_costs':   3'648     91'305    114'467       321   2'274'060      1'060'187\n",
      "\n",
      "Lp stats                      Component  Iterations  AddedCuts  OPTIMAL  DUAL_F.  DUAL_U.\n",
      "               'default_lp':          1      83'223          4   75'023        0       85\n",
      "                'fs_random':          1           0          0        0        3        0\n",
      "  'fs_random_quick_restart':          1           0          0        0        3        0\n",
      "           'lb_tree_search':          1         572          4   84'335       10        0\n",
      "                   'max_lp':          1      67'591         14  264'537      217       27\n",
      "      'objective_lb_search':          1      23'458          4   19'839        0       58\n",
      "                  'probing':          1      21'538          4   23'456       35        0\n",
      "             'pseudo_costs':          1      47'713         13  317'896       28       59\n",
      "            'quick_restart':          1      20'461          4   35'331        0      302\n",
      "            'reduced_costs':          1         390          7   95'380        6        0\n",
      "\n",
      "Lp dimension                                                               Final dimension of first component\n",
      "               'default_lp':  1 rows, 146 columns, 146 entries with magnitude in [1.000000e+00, 1.000000e+00]\n",
      "                'fs_random':    0 rows, 146 columns, 0 entries with magnitude in [0.000000e+00, 0.000000e+00]\n",
      "  'fs_random_quick_restart':    0 rows, 146 columns, 0 entries with magnitude in [0.000000e+00, 0.000000e+00]\n",
      "           'lb_tree_search':  1 rows, 438 columns, 146 entries with magnitude in [1.000000e+00, 1.000000e+00]\n",
      "                   'max_lp':  1 rows, 438 columns, 146 entries with magnitude in [1.000000e+00, 1.000000e+00]\n",
      "      'objective_lb_search':  2 rows, 146 columns, 292 entries with magnitude in [1.050210e-01, 1.000000e+00]\n",
      "                  'probing':  2 rows, 146 columns, 292 entries with magnitude in [1.050210e-01, 1.000000e+00]\n",
      "             'pseudo_costs':  1 rows, 438 columns, 146 entries with magnitude in [1.000000e+00, 1.000000e+00]\n",
      "            'quick_restart':  2 rows, 146 columns, 292 entries with magnitude in [1.050210e-01, 1.000000e+00]\n",
      "            'reduced_costs':  3 rows, 438 columns, 425 entries with magnitude in [3.162278e-01, 1.000000e+00]\n",
      "\n",
      "Lp debug                      CutPropag  CutEqPropag  Adjust  Overflow  Bad  BadScaling\n",
      "               'default_lp':          0            0     108         0    0           0\n",
      "                'fs_random':          0            0       0         0    0           0\n",
      "  'fs_random_quick_restart':          0            0       0         0    0           0\n",
      "           'lb_tree_search':          0            0       9         0    0           0\n",
      "                   'max_lp':          0            0   5'350         0    6           0\n",
      "      'objective_lb_search':          0            0   2'521         0    0           0\n",
      "                  'probing':          0            0     272         0    0           0\n",
      "             'pseudo_costs':          0            0     770         0    3           0\n",
      "            'quick_restart':          0            0      73         0    0           0\n",
      "            'reduced_costs':          0            0      10         0    0           0\n",
      "\n",
      "Lp pool                       Constraints  Updates  Simplif  Merged  Shortened  Split  Strenghtened  Cuts/Call\n",
      "               'default_lp':            5        0        0       0          0      0             0       4/64\n",
      "                'fs_random':            1        0        0       0          0      0             0        0/0\n",
      "  'fs_random_quick_restart':            1        0        0       0          0      0             0        0/0\n",
      "           'lb_tree_search':            5        0        0       0          0      0             0        4/4\n",
      "                   'max_lp':           15        0        0       0          0      0             0      14/68\n",
      "      'objective_lb_search':            5        0        0       0          0      0             0       4/12\n",
      "                  'probing':            5        0        0       0          0      0             0       4/76\n",
      "             'pseudo_costs':           14        0        0       0          0      0             0      13/86\n",
      "            'quick_restart':            5        0        0       0          0      0             0       4/20\n",
      "            'reduced_costs':            8        0        0       0          0      0             0       7/68\n",
      "\n",
      "Lp Cut                          default_lp  max_lp  quick_restart  reduced_costs  pseudo_costs  lb_tree_search  probing  objective_lb_search\n",
      "                         CG_R:           -       4              -              -             2               -        -                    -\n",
      "                     MIR_1_FF:           1       3              1              1             2               1        1                    1\n",
      "                      MIR_1_K:           1       3              1              1             2               1        1                    1\n",
      "                     MIR_1_KL:           1       1              1              1             1               1        1                    1\n",
      "                      MIR_1_R:           1       3              1              1             2               1        1                    1\n",
      "  NoOverlap2dXEnergy_optional:           -       -              -              3             4               -        -                    -\n",
      "\n",
      "LNS stats                        Improv/Calls  Closed  Difficulty  TimeLimit\n",
      "               'graph_arc_lns':           2/3     33%        0.31       0.10\n",
      "               'graph_cst_lns':           3/3     33%        0.31       0.10\n",
      "               'graph_dec_lns':           3/3     33%        0.31       0.10\n",
      "               'graph_var_lns':           2/3     33%        0.31       0.10\n",
      "     'packing_precedences_lns':           3/3      0%        0.12       0.10\n",
      "      'packing_rectangles_lns':           1/3      0%        0.12       0.10\n",
      "           'packing_slice_lns':           3/3      0%        0.12       0.10\n",
      "                   'rins/rens':           0/4     25%        0.19       0.10\n",
      "                 'rnd_cst_lns':           0/0      0%        0.50       0.10\n",
      "                 'rnd_var_lns':           3/4     50%        0.45       0.10\n",
      "  'scheduling_precedences_lns':           3/3      0%        0.12       0.10\n",
      "\n",
      "LS stats               Batches  Restarts  LinMoves  GenMoves  CompoundMoves  WeightUpdates\n",
      "   'fj_long_default':        0         0         0         0              0              0\n",
      "  'fj_short_default':        1         1         0         0              0              0\n",
      "      'violation_ls':        3         0         1       151              1          1'051\n",
      "\n",
      "Solutions (38)                Num     Rank\n",
      "         'fj_short_default':    1    [1,1]\n",
      "            'graph_dec_lns':    1  [31,31]\n",
      "            'graph_var_lns':    1  [27,27]\n",
      "  'packing_precedences_lns':    1  [28,28]\n",
      "        'packing_slice_lns':    1  [32,32]\n",
      "                  'probing':    2    [8,9]\n",
      "            'quick_restart':   10   [3,36]\n",
      "      'quick_restart_no_lp':   19   [2,37]\n",
      "              'rnd_var_lns':    2  [30,38]\n",
      "\n",
      "Objective bounds     Num\n",
      "      'default_lp':    1\n",
      "  'initial_domain':    1\n",
      "\n",
      "Solution repositories     Added  Queried  Ignored  Synchro\n",
      "  'feasible solutions':      73       77        0       67\n",
      "        'lp solutions':  10'162        4    6'119      677\n",
      "                'pump':       3        0\n",
      "\n",
      "CpSolverResponse summary:\n",
      "status: FEASIBLE\n",
      "objective: 105\n",
      "best_bound: 122\n",
      "integers: 451\n",
      "booleans: 146\n",
      "conflicts: 0\n",
      "branches: 22\n",
      "propagations: 0\n",
      "integer_propagations: 23\n",
      "restarts: 22\n",
      "lp_iterations: 0\n",
      "walltime: 60.029\n",
      "usertime: 60.029\n",
      "deterministic_time: 20.9606\n",
      "gap_integral: 60.5443\n",
      "solution_fingerprint: 0x4145d66f93dfad0e\n",
      "\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "2"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Solve!\n",
    "model.solve(60)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from solver import plot_solution\n",
    "\n",
    "# plot the solution\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "if model.solution is not None:\n",
    "    fig, ax = plt.subplots(1)\n",
    "    plot_solution(ax, instance, model.solution)\n",
    "    plt.show()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "mo312",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
